package org.dce.screencapturer.objects;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class ResizeHandler 
	implements MouseListener,MouseMotionListener{

	private DrawingObject drawingObject;
	
	public ResizeHandler(DrawingObject drawingObject){
		this.drawingObject = drawingObject;
		this.drawingObject.addMouseListener(this);
		this.drawingObject.addMouseMotionListener(this);
	}
	
	private class PickLocation {
		
		final boolean top;
		final boolean bottom;
		final boolean left;
		final boolean right;

		public PickLocation(boolean top,boolean bottom,boolean left,boolean right){
			this.top = top;
			this.bottom = bottom;
			this.left = left;
			this.right = right;
		}
	}

	private class ObjectState {
		private Rectangle bounds;
		private Point pickPoint;
		private PickLocation pickLocation;
		
		public ObjectState(MouseEvent event,PickLocation pickLocation){
			this.bounds = drawingObject.getBounds();
			this.pickPoint = event.getPoint();
			this.pickLocation = pickLocation;
		}
		
		public Rectangle getBounds() {
			return bounds;
		}
		public Point getPickPoint(){
			return pickPoint;
		}
		public PickLocation getPickLocation(){
			return pickLocation;
		}
	}
	private static final int RESIZE_THRESHOLD = 5;

	private ObjectState state;
	
	private ObjectState getState(MouseEvent e) {
		
		Point point = e.getPoint();
		
		final boolean top = point.getY() < RESIZE_THRESHOLD;
		final boolean bottom = point.getY() > drawingObject.getHeight() - RESIZE_THRESHOLD;
		final boolean left = point.getX() < RESIZE_THRESHOLD;
		final boolean right = point.getX() > drawingObject.getWidth() - RESIZE_THRESHOLD;
		
		return (top || left || bottom || right)
			? new ObjectState(e, new PickLocation(top,bottom,left,right))
			: null;
	}

	@Override
	public void mousePressed(MouseEvent e) {
		state = getState(e);
	}
	@Override
	public void mouseReleased(MouseEvent e) {
		
		if (state != null){
			drawingObject.firePropertyChange(
				"bounds", 
				state.getBounds(), 
				drawingObject.getBounds());
			state = null;
		}
	}
	@Override
	public void mouseDragged(MouseEvent e) {
		if (state != null){
			Point actualLocation = e.getComponent().getLocation();
			Rectangle currentBounds = state.getBounds();
			Point pickPoint = state.getPickPoint();
			Point point = e.getPoint();
			PickLocation pickLocation = state.getPickLocation();
			Rectangle newBounds = new Rectangle(currentBounds);
			
			if (pickLocation.top){
				newBounds.y = currentBounds.y-(point.y - pickPoint.y);
				newBounds.height = currentBounds.height + (point.y - pickPoint.y);
			}
			if (pickLocation.bottom){
				newBounds.height = currentBounds.height + (point.y - pickPoint.y);
			}
			if (pickLocation.right){
				newBounds.width = currentBounds.width + (point.x - pickPoint.x);
			}
			if (pickLocation.left){
				newBounds.x = actualLocation.x + (point.x - pickPoint.x);
				newBounds.width = currentBounds.width - (point.x - pickPoint.x);
			}
			
			drawingObject.setBounds(newBounds);
		}
	}

	public void mouseClicked(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}
	public void mouseMoved(MouseEvent e) {}

	public boolean isResizeEvent(MouseEvent event) {
		return getState(event) != null;
	}
	
}
